using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using UnityEngine;

public class Utils : MonoBehaviour
{
	public enum TouchState
	{
		unknown = -1,
		touchNone = 0,
		touchBegin = 1,
		touchMove = 2,
		touchEnd = 3
	}

	public const string kUnknown = "unknown";

	public const string kIphone = "iphone";

	public const string kIpad = "ipad";

	public const string kIphone5 = "iphone5";

	public const float ipadRatio = 1.3333334f;

	public const float iphoneRatio = 1.5f;

	public const float iphone5Ratio = 1.775f;

	public const float iphone5Ratio169 = 1.7777778f;

	public const float iPhone6DPI = 326f;

	public const float iPhone6ScreenHeight = 750f;

	public const float iPhone6ScreenSize = 2.3006134f;

	public const float iPhone6ScreenTouchLimit = 150f;

	public const float iPhone6FPS = 60f;

	public const float ipadDPI = 130f;

	private static float screenTouchLimit = 1000f;

	private static string outputListDir = string.Empty;

	public static string getDeviceType()
	{
		float num = (float)Screen.width / (float)Screen.height;
		if (num == 1.5f)
		{
			return "iphone";
		}
		if (num == 1.3333334f)
		{
			return "ipad";
		}
		if (num == 1.775f || (num > 1.6f && num < 1.9555556f))
		{
			return "iphone5";
		}
		return "unknown";
	}

	public static bool isRetinaDevice()
	{
		if (getDeviceType() == "ipad" && Screen.width > 1500)
		{
			return true;
		}
		if (getDeviceType() == "iphone" && Screen.width > 500)
		{
			return true;
		}
		if (getDeviceType() == "iphone5" && Screen.width > 500)
		{
			return true;
		}
		return false;
	}

	public static float GetDPI()
	{
		float num = Screen.dpi;
		if (num < 100f || num > 1500f)
		{
			num = 160f;
		}
		return num;
	}

	public static float GetDPIratio()
	{
		return GetDPI() / 130f;
	}

	public static bool isDPIAvailable()
	{
		if (Screen.dpi > 100f && Screen.dpi < 1500f)
		{
			return true;
		}
		return false;
	}

	public static float GetScreenTouchMultiplier()
	{
		if (isDPIAvailable())
		{
			return 326f / Screen.dpi;
		}
		return 750f / (float)Screen.height;
	}

	public static float GetScreenTouchLimit(bool recalculate = false, float fps = 60f)
	{
		if (recalculate)
		{
			if (isDPIAvailable())
			{
				float num = (float)Screen.height / Screen.dpi;
				float num2 = num / 2.3006134f;
				float num3 = 60f / fps;
				num2 = 1f + (num2 - 1f) * 0.66f;
				screenTouchLimit = 150f / num2 * num3;
			}
			else
			{
				screenTouchLimit = 1000f;
			}
		}
		if (screenTouchLimit < 75f)
		{
			return 75f;
		}
		return screenTouchLimit;
	}

	public static bool isHighResDevice()
	{
		if (Screen.width > 1366)
		{
			return true;
		}
		return false;
	}

	public static bool isSlowDevice()
	{
		return false;
	}

	public static string stripFileNameDeviceSuffix(string fileName)
	{
		string text = fileName;
		text = text.Replace("@2x", string.Empty);
		text = text.Replace("~ipad", string.Empty);
		text = text.Replace("~iphone5", string.Empty);
		return text.Replace("~iphone", string.Empty);
	}

	public static string getFileNameDeviceSuffix()
	{
		string text = string.Empty;
		if (getDeviceType() == "ipad")
		{
			text += "~ipad";
		}
		if (getDeviceType() == "iphone")
		{
			text += "~iphone";
		}
		if (getDeviceType() == "iphone5")
		{
			text += "~iphone5";
		}
		if (isRetinaDevice())
		{
			text += "@2x";
		}
		return text;
	}

	public static string stripFileNameMultiplierDeviceSuffix(string fileName)
	{
		string text = fileName;
		text = text.Replace("@1x", string.Empty);
		text = text.Replace("@2x", string.Empty);
		return text.Replace("@4x", string.Empty);
	}

	public static string NO_USE_getFileNameMultiplierDeviceSuffix()
	{
		int num = 1;
		if (getDeviceType() == "ipad")
		{
			num *= 2;
		}
		if (isRetinaDevice())
		{
			num *= 2;
		}
		return "@" + num + "x";
	}

	public static Vector2 getTouchPositionVector2(int mouseButton = 0)
	{
		Vector2 result = Vector2.zero;
		if (Input.touchCount > 0)
		{
			Touch touch = Input.touches[0];
			result = touch.position;
		}
		else if (Input.GetMouseButton(mouseButton) || Input.GetMouseButtonUp(mouseButton) || Input.GetMouseButtonDown(mouseButton))
		{
			Vector3 mousePosition = Input.mousePosition;
			result = new Vector2(mousePosition.x, mousePosition.y);
		}
		return result;
	}

	public static Vector3 getTouchPositionVector3(int mouseButton = 0)
	{
		Vector3 result = Vector3.zero;
		if (Input.touchCount > 0)
		{
			Touch touch = Input.touches[0];
			result = new Vector3(touch.position.x, touch.position.y, 0f);
		}
		else if (Input.GetMouseButton(mouseButton) || Input.GetMouseButtonUp(mouseButton) || Input.GetMouseButtonDown(mouseButton))
		{
			result = Input.mousePosition;
		}
		return result;
	}

	public static TouchState getTouchState(int mouseButton = 0)
	{
		TouchState result = TouchState.touchNone;
		if (Input.touchCount > 0)
		{
			Touch touch = Input.touches[0];
			result = ((touch.phase == TouchPhase.Began) ? TouchState.touchBegin : ((touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled) ? TouchState.touchMove : TouchState.touchEnd));
		}
		else if (Input.GetMouseButtonDown(mouseButton))
		{
			result = TouchState.touchBegin;
		}
		else if (Input.GetMouseButtonUp(mouseButton))
		{
			result = TouchState.touchEnd;
		}
		else if (Input.GetMouseButton(mouseButton))
		{
			result = TouchState.touchMove;
		}
		return result;
	}

	public static int getTouchCount()
	{
		if (Input.touchCount == 0 && Input.GetMouseButton(0))
		{
			return 1;
		}
		return Input.touchCount;
	}

	public static bool getTouchForFingerId(int fingerId, out Touch theTouch)
	{
		theTouch = default(Touch);
		Touch[] touches = Input.touches;
		for (int i = 0; i < touches.Length; i++)
		{
			Touch touch = touches[i];
			if (touch.fingerId == fingerId)
			{
				theTouch = touch;
				return true;
			}
		}
		return false;
	}

	public static Vector3 vector2ToVector3(Vector2 v)
	{
		return new Vector3(v.x, v.y, 0f);
	}

	public static Vector3 getScreenPointOnPlane(Vector3 scrPoint, Plane plane, Camera cam)
	{
		Ray ray = cam.ScreenPointToRay(scrPoint);
		float enter;
		plane.Raycast(ray, out enter);
		return ray.GetPoint(enter);
	}

	public static Color lightenColor(Color col, float amount)
	{
		float r = col.r;
		float g = col.g;
		float b = col.b;
		r = (1f - col.r) * amount + col.r;
		g = (1f - col.g) * amount + col.g;
		b = (1f - col.b) * amount + col.b;
		if (r > 1f || g > 1f || b > 1f)
		{
			return col;
		}
		return new Color(r, g, b, col.a);
	}

	public static Color DesaturateColor(Color col, float amount)
	{
		float num = 0.3f * col.r + 0.6f * col.g + 0.1f * col.b;
		float r = col.r + amount * (num - col.r);
		float g = col.g + amount * (num - col.g);
		float b = col.b + amount * (num - col.b);
		return new Color(r, g, b, col.a);
	}

	public static Color ColorFromHSV(float h, float s, float v, float a = 1f)
	{
		if (s == 0f)
		{
			return new Color(v, v, v, a);
		}
		float num = h / 60f;
		int num2 = (int)num;
		float num3 = num - (float)num2;
		float num4 = v * (1f - s);
		float num5 = v * (1f - s * num3);
		float num6 = v * (1f - s * (1f - num3));
		Color result = new Color(0f, 0f, 0f, a);
		switch (num2)
		{
		case 0:
			result.r = v;
			result.g = num6;
			result.b = num4;
			break;
		case 1:
			result.r = num5;
			result.g = v;
			result.b = num4;
			break;
		case 2:
			result.r = num4;
			result.g = v;
			result.b = num6;
			break;
		case 3:
			result.r = num4;
			result.g = num5;
			result.b = v;
			break;
		case 4:
			result.r = num6;
			result.g = num4;
			result.b = v;
			break;
		default:
			result.r = v;
			result.g = num4;
			result.b = num5;
			break;
		}
		return result;
	}

	public static Color SetAlpha(Color color, float alpha)
	{
		return new Color(color.r, color.g, color.b, alpha);
	}

	public static float RoundFloat(float number, int decimals = 2)
	{
		return Mathf.Round(number * Mathf.Pow(10f, decimals)) / Mathf.Pow(10f, decimals);
	}

	public static Vector3 RoundVector3(Vector3 vector, int decimals = 2)
	{
		Vector3 result = vector;
		result.x = RoundFloat(result.x, decimals);
		result.y = RoundFloat(result.y, decimals);
		result.z = RoundFloat(result.z, decimals);
		return result;
	}

	public static Vector3 ClampVector3(Vector3 vector, Vector3 minim, Vector3 maxim)
	{
		Vector3 result = vector;
		result.x = Mathf.Clamp(vector.x, minim.x, maxim.x);
		result.y = Mathf.Clamp(vector.y, minim.y, maxim.y);
		result.z = Mathf.Clamp(vector.z, minim.z, maxim.z);
		return result;
	}

	public static string Vector3ToString(Vector3 vector, int decimals = 2)
	{
		string empty = string.Empty;
		empty += RoundFloat(vector.x, decimals).ToString("F" + decimals);
		empty += ";";
		empty += RoundFloat(vector.y, decimals).ToString("F" + decimals);
		empty += ";";
		return empty + RoundFloat(vector.z, decimals).ToString("F" + decimals);
	}

	public static string QuaternionToString(Quaternion quaternion, int decimals = 2)
	{
		string empty = string.Empty;
		empty += RoundFloat(quaternion.w, decimals).ToString("F" + decimals);
		empty += ";";
		empty += RoundFloat(quaternion.x, decimals).ToString("F" + decimals);
		empty += ";";
		empty += RoundFloat(quaternion.y, decimals).ToString("F" + decimals);
		empty += ";";
		return empty + RoundFloat(quaternion.z, decimals).ToString("F" + decimals);
	}

	public static Vector3 StringToVector3(string text)
	{
		Vector3 zero = Vector3.zero;
		string[] array = text.Split(';');
		if (array.Length != 3)
		{
			Debug.Log("StringToVector3 Failed:" + text);
			return zero;
		}
		zero.x = float.Parse(array[0]);
		zero.y = float.Parse(array[1]);
		zero.z = float.Parse(array[2]);
		return zero;
	}

	public static Quaternion StringToQuaternion(string text)
	{
		Quaternion identity = Quaternion.identity;
		string[] array = text.Split(';');
		if (array.Length != 4)
		{
			Debug.Log("StringToQuaternion Failed:" + text);
			return identity;
		}
		identity.w = float.Parse(array[0]);
		identity.x = float.Parse(array[1]);
		identity.y = float.Parse(array[2]);
		identity.z = float.Parse(array[3]);
		return identity;
	}

	public static int ColorToInt(Color32 colorRGB)
	{
		return colorRGB.r * 256 * 256 + colorRGB.g * 256 + colorRGB.b;
	}

	public static Color32 IntToColor(int colorINT)
	{
		Color32 result = new Color32(0, 0, 0, byte.MaxValue);
		result.b = (byte)(colorINT % 256);
		result.g = (byte)(colorINT / 256 % 256);
		result.r = (byte)(colorINT / 256 / 256 % 256);
		return result;
	}

	public static string ColorToHex(Color32 color)
	{
		return color.r.ToString("X2") + color.g.ToString("X2") + color.b.ToString("X2");
	}

	public static Color32 HexToColor(string hex)
	{
		byte r = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber);
		byte g = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber);
		byte b = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber);
		return new Color32(r, g, b, byte.MaxValue);
	}

	public static Bounds Rotate90Bounds(Bounds bounds, Vector3 toRotate)
	{
		bounds.extents = Quaternion.Euler(toRotate) * bounds.extents;
		bounds.extents = new Vector3(Mathf.Abs(bounds.extents.x), Mathf.Abs(bounds.extents.y), Mathf.Abs(bounds.extents.z));
		toRotate.Normalize();
		float num = 0f;
		if (toRotate.x != 0f)
		{
			num = bounds.size.y + bounds.size.z;
			if (RoundFloat(num, 0) % 2f == 1f)
			{
				if (bounds.size.y < bounds.size.z)
				{
					bounds.center += new Vector3(0f, 0.5f, 0.5f);
				}
				else
				{
					bounds.center += new Vector3(0f, -0.5f, -0.5f);
				}
			}
		}
		else if (toRotate.y != 0f)
		{
			num = bounds.size.x + bounds.size.z;
			if (RoundFloat(num, 0) % 2f == 1f)
			{
				if (bounds.size.z < bounds.size.x)
				{
					bounds.center += new Vector3(0.5f, 0f, 0.5f);
				}
				else
				{
					bounds.center += new Vector3(-0.5f, 0f, -0.5f);
				}
			}
		}
		else if (toRotate.z != 0f)
		{
			num = bounds.size.x + bounds.size.y;
			if (RoundFloat(num, 0) % 2f == 1f)
			{
				if (bounds.size.y < bounds.size.x)
				{
					bounds.center += new Vector3(0.5f, 0.5f, 0f);
				}
				else
				{
					bounds.center += new Vector3(-0.5f, -0.5f, 0f);
				}
			}
		}
		return bounds;
	}

	public static float DistanceToRay(Vector3 X0, Ray ray)
	{
		Vector3 origin = ray.origin;
		Vector3 vector = ray.origin + ray.direction;
		Vector3 lhs = X0 - origin;
		Vector3 rhs = X0 - vector;
		return Vector3.Cross(lhs, rhs).magnitude / (origin - vector).magnitude;
	}

	public static bool IsInLayerMask(GameObject obj, LayerMask mask)
	{
		return (mask.value & (1 << obj.layer)) > 0;
	}

	public static void ChangeLayerRecursive(GameObject targetObject, int newLayer)
	{
		if (targetObject == null || targetObject.layer == newLayer)
		{
			return;
		}
		targetObject.layer = newLayer;
		foreach (Transform item in targetObject.transform)
		{
			ChangeLayerRecursive(item.gameObject, newLayer);
		}
	}

	public static void GetSplitedTime(float time, out int minutes, out int seconds, out int hundreds)
	{
		time = RoundFloat(time);
		minutes = Mathf.FloorToInt(time) / 60;
		seconds = Mathf.FloorToInt(time) % 60;
		string text = time.ToString("F2");
		hundreds = int.Parse(text.Substring(text.Length - 2, 2));
	}

	public static bool DecodeTimeSpan(string encoded, out TimeSpan timeSpan)
	{
		if (encoded != null && encoded != string.Empty && encoded != string.Empty)
		{
			string[] array = encoded.Split(',');
			if (array != null && array.Length >= 4)
			{
				int days = int.Parse(array[0]);
				int hours = int.Parse(array[1]);
				int minutes = int.Parse(array[2]);
				int seconds = int.Parse(array[3]);
				int milliseconds = 0;
				if (array.Length == 5)
				{
					milliseconds = int.Parse(array[4]);
				}
				timeSpan = new TimeSpan(days, hours, minutes, seconds, milliseconds);
				return true;
			}
		}
		timeSpan = default(TimeSpan);
		return false;
	}

	public static string EncodeTimeSpan(TimeSpan timeSpan)
	{
		int days = timeSpan.Days;
		int hours = timeSpan.Hours;
		int minutes = timeSpan.Minutes;
		int seconds = timeSpan.Seconds;
		int milliseconds = timeSpan.Milliseconds;
		string text = days + "," + hours + "," + minutes + "," + seconds;
		if (milliseconds != 0)
		{
			text += milliseconds;
		}
		return text;
	}

	public static bool DecodeTimeSpanList(string encoded, out List<TimeSpan> timeSpanList, char separator = '|')
	{
		timeSpanList = new List<TimeSpan>();
		bool result = true;
		if (encoded != null && encoded != string.Empty && encoded != string.Empty)
		{
			string[] array = encoded.Split(separator);
			if (array != null && array.Length > 0)
			{
				string[] array2 = array;
				foreach (string text in array2)
				{
					if (text != null && text != string.Empty && text != string.Empty)
					{
						TimeSpan timeSpan;
						if (DecodeTimeSpan(text, out timeSpan))
						{
							timeSpanList.Add(timeSpan);
						}
						else
						{
							result = false;
						}
					}
				}
			}
		}
		return result;
	}

	public static string EncodeTimeSpanList(List<TimeSpan> timeSpanList, char separator = '|')
	{
		string text = string.Empty;
		for (int i = 0; i < timeSpanList.Count; i++)
		{
			text += EncodeTimeSpan(timeSpanList[i]);
			if (i < timeSpanList.Count - 1)
			{
				text += separator;
			}
		}
		return text;
	}

	private static void ListDirRecursive(string path, int depth)
	{
		try
		{
			DirectoryInfo directoryInfo = new DirectoryInfo(path);
			if (directoryInfo != null)
			{
				float num = 0f;
				FileInfo[] files = directoryInfo.GetFiles();
				foreach (FileInfo fileInfo in files)
				{
					num += (float)fileInfo.Length;
				}
				outputListDir += new string('\t', depth);
				string text = outputListDir;
				outputListDir = text + directoryInfo.Name + " : files size = " + (num / 1000000f).ToString("F4") + " MB";
				outputListDir += '\n';
				DirectoryInfo[] directories = directoryInfo.GetDirectories();
				foreach (DirectoryInfo directoryInfo2 in directories)
				{
					ListDirRecursive(directoryInfo2.FullName, depth + 1);
				}
				FileInfo[] files2 = directoryInfo.GetFiles();
				foreach (FileInfo fileInfo2 in files2)
				{
					outputListDir += new string('\t', depth + 1);
					text = outputListDir;
					outputListDir = text + fileInfo2.Name + " : size = " + ((float)fileInfo2.Length / 1000000f).ToString("F4") + " MB";
					outputListDir += '\n';
				}
			}
		}
		catch (IOException ex)
		{
			outputListDir += ex;
		}
		catch
		{
		}
	}

	public static string ListDirectory(string path)
	{
		outputListDir = string.Empty;
		ListDirRecursive(path, 1);
		return outputListDir;
	}

	public static float roundZecimals(float number, int zecimals = 3)
	{
		float num = number;
		num *= 10f * (float)zecimals;
		num = Mathf.Round(num);
		return num / (10f * (float)zecimals);
	}

	public static Vector3 roundZecimals(Vector3 vector, int zecimals = 3)
	{
		Vector3 result = vector;
		result.x = roundZecimals(result.x, zecimals);
		result.y = roundZecimals(result.y, zecimals);
		result.z = roundZecimals(result.z, zecimals);
		return result;
	}

	public static float GetBoundsDiagonal(Bounds bounds)
	{
		return Mathf.Sqrt(bounds.size.x * bounds.size.x + bounds.size.y * bounds.size.y + bounds.size.z * bounds.size.z);
	}

	public static bool AreEqualBounds(Bounds boundsA, Bounds boundsB)
	{
		if (boundsA.center == boundsB.center && boundsA.size == boundsB.size)
		{
			return true;
		}
		return false;
	}

	public static Bounds CopyOfBounds(Bounds original)
	{
		return new Bounds(original.center, original.size);
	}

	public static Vector3 GetPositionAlignXLeftOut(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.x = alignTo.center.x - alignTo.extents.x - align.extents.x;
		return center;
	}

	public static Vector3 GetPositionAlignXLeftIn(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.x = alignTo.center.x - alignTo.extents.x + align.extents.x;
		return center;
	}

	public static Vector3 GetPositionAlignXCenter(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.x = alignTo.center.x;
		return center;
	}

	public static Vector3 GetPositionAlignXRightIn(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.x = alignTo.center.x + alignTo.extents.x - align.extents.x;
		return center;
	}

	public static Vector3 GetPositionAlignXRightOut(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.x = alignTo.center.x + alignTo.extents.x + align.extents.x;
		return center;
	}

	public static Vector3 GetPositionAlignYLeftOut(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.y = alignTo.center.y - alignTo.extents.y - align.extents.y;
		return center;
	}

	public static Vector3 GetPositionAlignYLeftIn(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.y = alignTo.center.y - alignTo.extents.y + align.extents.y;
		return center;
	}

	public static Vector3 GetPositionAlignYCenter(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.y = alignTo.center.y;
		return center;
	}

	public static Vector3 GetPositionAlignYRightIn(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.y = alignTo.center.y + alignTo.extents.y - align.extents.y;
		return center;
	}

	public static Vector3 GetPositionAlignYRightOut(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.y = alignTo.center.y + alignTo.extents.y + align.extents.y;
		return center;
	}

	public static Vector3 GetPositionAlignZLeftOut(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.z = alignTo.center.z - alignTo.extents.z - align.extents.z;
		return center;
	}

	public static Vector3 GetPositionAlignZLeftIn(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.z = alignTo.center.z - alignTo.extents.z + align.extents.z;
		return center;
	}

	public static Vector3 GetPositionAlignZCenter(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.z = alignTo.center.z;
		return center;
	}

	public static Vector3 GetPositionAlignZRightIn(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.z = alignTo.center.z + alignTo.extents.z - align.extents.z;
		return center;
	}

	public static Vector3 GetPositionAlignZRightOut(Bounds align, Bounds alignTo)
	{
		Vector3 center = align.center;
		center.z = alignTo.center.z + alignTo.extents.z + align.extents.z;
		return center;
	}
}
